package br.com.diego.system.manager.componente.impl;

import br.com.diego.system.controller.consultacomponente.ConsultaComponenteVo;
import br.com.diego.system.controller.consultacomponente.TipoConsultaVo;
import br.com.diego.system.entity.componente.Componente;
import br.com.diego.system.manager.AbstractDiegoManager;
import br.com.diego.system.manager.componente.ComponenteManager;
import java.util.List;
import javax.persistence.NoResultException;
import javax.persistence.OptimisticLockException;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.transaction.annotation.Transactional;

public class JpaComponenteManagerImpl extends AbstractDiegoManager implements ComponenteManager {
    
    @Override
    @Transactional(readOnly = false)
    public void salvar(Componente componente) {
        if (componente.getId() == null) {
            entityManager.persist(componente);
        }else{
            try {     
                entityManager.merge(componente);
            }catch(OptimisticLockException e){
                throw new IllegalArgumentException(
                        "Estes dados foram alterados por outro usuario.");
            }    
        }
    }

    @Override
    @Transactional(readOnly = false)
    public void deletar(Componente componente) {
        componente =  buscarPeloId(componente.getId());
        entityManager.remove(componente);
    }

    @Override
    @Transactional(readOnly = true)
    public Componente buscarPeloId(Long id) {
        return entityManager.find(Componente.class, id);
    }

    @Override
    @Transactional(readOnly = true)
    public Componente verificaNomeUnico(Componente componente) {
        Session session = (Session) entityManager.getDelegate();
        Criteria criteria =  session.createCriteria(Componente.class)
                .add(Restrictions.eq("nome", componente.getNome()));
        if (componente.getId() != null) {
            criteria.add(Restrictions.ne("id", componente.getId()));
        }
        
        try {
            return (Componente) criteria.uniqueResult();
        }catch(NoResultException e){
            return null;
        }
    }

    @Override
    @Transactional(readOnly = true)
    public List<Componente> consultar(ConsultaComponenteVo consultaComponenteVo) {
        Session session = (Session) entityManager.getDelegate();
        Criteria criteria = session.createCriteria(Componente.class);
        
        if (consultaComponenteVo.getTipoConsultaVo() == TipoConsultaVo.ID) {
            try {
                criteria.add(Restrictions.eq("id", Long.valueOf(consultaComponenteVo.getFiltro())));
            } catch (IllegalArgumentException e) {
                throw new IllegalArgumentException("Valor informado invalido");
            }
        }else if(consultaComponenteVo.getTipoConsultaVo() == TipoConsultaVo.NOME){        
            criteria.add(Restrictions.ilike("nome", String.format("%%%s%%", consultaComponenteVo.getFiltro())));        
            criteria.addOrder(Order.asc("nome"));
        }else{
            criteria.addOrder(Order.asc("nome"));
        }        
        return criteria.list();
    }
    
}
